package com.dynamic.mybatis.core.session;

import com.dynamic.mybatis.core.enums.CommandType;
import com.dynamic.mybatis.core.metadata.DynamicMappedStatement;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.TransactionIsolationLevel;
import org.springframework.transaction.support.ResourceHolder;
import org.springframework.transaction.support.TransactionSynchronizationManager;

/**
 * @Description 生成动态sql后会执行sql, 验证sql是否正确
 * @Author xs
 * @Date 2021/3/24 18:02
 */
public abstract class DynamicSqlSessionPreparedStatement extends DynamicSqlSessionInterceptHandler {

    public <T> T executeTest(DynamicMappedStatement dms) {
        return executeTest(dms, null, null);
    }

    public <T> T executeTest(DynamicMappedStatement dms, Object parameter) {
        return executeTest(dms, parameter, null);
    }


    /**
     * @param dms
     * @param parameter 参数(一般使用Map)
     * @param parameter 分页参数说明
     *                  pageNumber 当前页码从1开始，默认为1。 pageSize 每页数量，默认为10
     *                  offset 起始行下标从0开始  limit 筛选数量
     *                  示例 {"pageNumber":1,"pageSize":10}或{offset:0,limit:10}
     * @Description: 执行SQl后不会删除mappedStatement, 下次直接调用execute执行
     */
    public <T> T executeTest(DynamicMappedStatement dms, Object parameter, Object dataSourceKey) {
        return executeRollback(dms, parameter, dataSourceKey);
    }

    protected <T> T executeRollback(DynamicMappedStatement dms, Object parameter, Object dataSourceKey) {
        SqlSession sqlSession;
        if(dms.getCommandType() != CommandType.StandardCommand.SELECT){
            ExecutorType executorType = dms.isBatch() ? ExecutorType.BATCH : ExecutorType.SIMPLE;
            sqlSession = getSqlSqlSessionFactory().openSession(executorType, Boolean.FALSE);
        }else {
            sqlSession = getSqlSqlSessionFactory().openSession();
        }
        try {
            return getDynamicSqlSession().execute(sqlSession, dms, parameter, dataSourceKey, false);
        } finally {
            if (sqlSession != null) {
                if (dms.getCommandType() != CommandType.StandardCommand.SELECT) {
                    sqlSession.rollback(true);
                } else {
                    sqlSession.flushStatements();
                }
            }
            sqlSession.close();
        }
    }

}